package cn.edu.ecust.market.controller;

import cn.edu.ecust.market.entity.Order;
import cn.edu.ecust.market.entity.Product;
import cn.edu.ecust.market.result.Result;
import cn.edu.ecust.market.service.IOrderService;
import cn.edu.ecust.market.service.IProductService;
import cn.edu.ecust.market.util.JwtUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 订单服务
 */
@RestController
public class OrderController {

    @Autowired
    private IOrderService orderService;
    @Autowired
    private IProductService productService;
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 下单接口
     * 必须登录 必须没买过 必须有库存
     * 减库存创建订单
     */
    @PostMapping("/order")
    @Transactional
    public Result<Void> createOrder(@RequestBody Map<String,String> params, HttpServletRequest request) {
        // 认证
        String token = request.getHeader("token");
        Claims claims = JwtUtil.parserToken(token);
        if(claims == null){
            return Result.fail(401, "请先登录");
        }
        // 获取参数
        Long productId = Long.parseLong(params.get("productId"));
        Long userId = claims.get("id", Long.class);
        // 加锁
        RLock lock = redissonClient.getLock(productId.toString());
        lock.lock();
        try {
            // 检查是否买过
            List<Order> orderList = orderService.list(new LambdaQueryWrapper<>(Order.class)
                    .eq(Order::getProductId, productId)
                    .eq(Order::getUserId, userId)
            );
            if(!CollectionUtils.isEmpty(orderList)) {
                return Result.fail(400, "您已经购买过该商品");
            }
            // 检查库存
            Product product = productService.getById(productId);
            if(product.getInventory() <= 0) {
                return Result.fail(400, "库存不足");
            }
            // 减库存
            product.setInventory(product.getInventory() - 1);
            productService.updateById(product);
            // 创建订单
            Order order = new Order();
            order.setState(1);
            order.setTime(LocalDateTime.now());
            order.setUserId(userId);
            order.setProductId(productId);
            order.setProductTitle(product.getTitle());
            order.setProductPrice(product.getPrice());
            order.setProductImg(product.getImg());
            orderService.save(order);
            // 返回
            return Result.success();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 支付
     * 必须登录
     * 订单必须为创建
     * 更新订单
     */
    @PostMapping("/order/{orderId}")
    public Result<Void> updateOrder(@PathVariable Long orderId, HttpServletRequest request) {
        // 认证
        String token = request.getHeader("token");
        Claims claims = JwtUtil.parserToken(token);
        if(claims == null){
            return Result.fail(401, "请先登录");
        }
        // 获取参数
        Order order = orderService.getById(orderId);
        // 订单不存在或不是创建状态
        if(order == null || order.getState() != 1) {
            return Result.fail(400, "订单不存在或已过期");
        }
        // 更新订单状态
        order.setState(2);
        orderService.updateById(order);
        return Result.success();
    }

    /**
     * 获取用户自己的订单列表
     */
    @GetMapping("/order")
    public Result<List<Order>> getOrderList(Long productId, HttpServletRequest request) {
        // 认证
        String token = request.getHeader("token");
        Claims claims = JwtUtil.parserToken(token);
        if(claims == null){
            return Result.fail(401, "请先登录");
        }
        // 获取参数
        Long userId = claims.get("id", Long.class);
        // 获取订单列表
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<Order>()
                .eq(Order::getUserId, userId);
        if(productId != null) {
            wrapper.eq(Order::getProductId, productId);
        }
        List<Order> orderList = orderService.list(wrapper);
        return Result.success(orderList);
    }

}
